using System;
using System.Collections.Generic;
using System.Text;

namespace tp3
{
    public class Plano
    {
        private static double largo = 0.5d;
        private static double alto = 0.1d;
        private static double zero = 0.0000000000001;

        public static List<List<Punto>> CalcularPuntos(Punto direccion, Punto centro)
        {
            Punto w = new Punto(direccion.X - centro.X, direccion.Y - centro.Y, direccion.Z - centro.Z);

            if (Math.Abs(w.X) <= zero)
            {
                w.X = 0;
            }
            if (Math.Abs(w.Y) <= zero)
            {
                w.Y = 0;
            }

            double aux = Math.Sqrt(w.X * w.X + w.Y * w.Y + w.Z * w.Z);
            if (Math.Abs(aux) <= zero)
                return new List<List<Punto>>();

            if (aux != 0)
            {
                w.X /= aux;
                w.Y /= aux;
                w.Z /= aux;
            }

            if (w.X == 0 && w.Y == 0 && Math.Abs(w.Z) == 1.0d)
                return new List<List<Punto>>();

            Punto u = new Punto();

            if (w.X == 0 && w.Y == 0 && w.Z == 0)
                return new List<List<Punto>>();


            if (Math.Abs(w.X) >= Math.Abs(w.Y))
            {
                double factor = 1 / Math.Sqrt(w.X * w.X + w.Z * w.Z);
                u.X = -w.Z * factor;
                u.Y = 0;
                u.Z = w.X * factor;
            }
            else
            {
                double factor = 1 / Math.Sqrt(w.Y * w.Y + w.Z * w.Z);
                u.X = 0;
                u.Y = w.Z * factor;
                u.Z = -w.Y * factor;
            }

            if (u.Z < 0d)
            {
                u.X = -u.X;
                u.Y = -u.Y;
                u.Z = -u.Z;
            }

            Punto v = new Punto(w.Y * u.Z - w.Z * u.Y, w.Z * u.X - w.X * u.Z, w.X * u.Y - w.Y * u.X);

            v.X *= largo;
            v.Y *= largo;
            v.Z *= largo;

            List<List<Punto>> resultado = new List<List<Punto>>();
            List<Punto> listaPuntos = new List<Punto>();
            List<Punto> listaNormales = new List<Punto>();

            //Superior Izquierdo
            Punto puntoSuperiorIzquierdo = new Punto(centro.X - v.X, centro.Y - v.Y, centro.Z + alto);
            Punto normalSuperiorIzquierda = new Punto(puntoSuperiorIzquierdo.X - centro.X,
                puntoSuperiorIzquierdo.Y - centro.Y,
                0);
            //InferiorIzquierdo
            Punto puntoInferiorIzquierdo = new Punto(centro.X - v.X, centro.Y - v.Y, centro.Z);
            Punto normalInferiorIzquierda = new Punto(puntoInferiorIzquierdo.X - centro.X,
                puntoInferiorIzquierdo.Y - centro.Y,
                -1);
            //Superior Derecho
            Punto puntoSuperiorDerecho = new Punto(centro.X + v.X, centro.Y + v.Y, centro.Z + alto);
            Punto normalSuperiorDerecha = new Punto(puntoSuperiorDerecho.X - centro.X,
                puntoSuperiorDerecho.Y - centro.Y,
                0);
            //InferiorDerecho
            Punto puntoInferiorDerecho = new Punto(centro.X + v.X, centro.Y + v.Y, centro.Z);
            Punto normalInferiorDerecha = new Punto(puntoInferiorDerecho.X - centro.X,
                puntoInferiorDerecho.Y - centro.Y,
                -1);

            listaNormales.Add(normalSuperiorIzquierda);
            listaNormales.Add(normalInferiorIzquierda);
            listaNormales.Add(normalInferiorDerecha);
            listaNormales.Add(normalSuperiorDerecha);

            listaPuntos.Add(puntoSuperiorIzquierdo);
            listaPuntos.Add(puntoInferiorIzquierdo);
            listaPuntos.Add(puntoInferiorDerecho);
            listaPuntos.Add(puntoSuperiorDerecho);

            resultado.Add(listaNormales);
            resultado.Add(listaPuntos);

            return resultado;
        }
    }
}
